package com.xgpush;

import android.content.Context;
import android.os.Environment;
import android.widget.Toast;
import android.util.Log;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.tencent.android.tpush.NotificationAction;
import com.tencent.android.tpush.XGPushBaseReceiver;
import com.tencent.android.tpush.XGPushClickedResult;
import com.tencent.android.tpush.XGPushConfig;
import com.tencent.android.tpush.XGPushManager;
import com.tencent.android.tpush.XGPushRegisterResult;
import com.tencent.android.tpush.XGPushShowedResult;
import com.tencent.android.tpush.XGPushTextMessage;
import com.tencent.android.tpush.common.ReturnCode;

import org.afinal.simplecache.ACache;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by asus on 2018-06-28.
 */

public class TPushModule extends BaseModule {

    protected ReactApplicationContext context;

    private final static String RNXG_ON_REGISTER = "RNXG_ON_REGISTER";
    private final static String RNXG_ON_UNREGISTER = "RNXG_ON_UNREGISTER";
    private final static String RNXG_NOTIFICATION_ON_RECEIVE = "RNXG_NOTIFICATION_ON_RECEIVE";
    private final static String RNXG_NOTIFICATION_ON_CLICK = "RNXG_NOTIFICATION_ON_CLICK";
    private final static String RNXG_TEXTMESSAGE_ON_RECEIVE = "RNXG_TEXTMESSAGE_ON_RECEIVE";
    private final static String RNXG_ON_SET_TAG = "RNXG_ON_SET_TAG";
    private final static String RNXG_ON_DELETE_TAG = "RNXG_ON_DELETE_TAG";

    private static WritableMap launchAppNotification = null;
    private static boolean jsDidLoad = false;
    private final static Object notificationCacheLockObject = new Object();
    private static ACache notificationCache = null;
    private static JSONArray notificationIdList = null;

    private final static String NOTIFICATION_CACHE_NAME = "rnxg";

    public TPushModule(ReactApplicationContext reactApplicationContext) {
        super(reactApplicationContext);
        context = reactApplicationContext;
    }

    @Override
    public Map<String, Object> getConstants() {
        Map<String, Object> constants = new HashMap<>();
        constants.put(RNXG_ON_REGISTER, RNXG_ON_REGISTER);
        constants.put(RNXG_ON_UNREGISTER, RNXG_ON_UNREGISTER);
        constants.put(RNXG_NOTIFICATION_ON_RECEIVE, RNXG_NOTIFICATION_ON_RECEIVE);
        constants.put(RNXG_NOTIFICATION_ON_CLICK, RNXG_NOTIFICATION_ON_CLICK);

        return constants;
    }

    /*
     * 定义一个方法，获取应用包名
     * */
    @ReactMethod
    public void getPackageName() {
        String name = getReactApplicationContext().getPackageName();
        Toast.makeText(getReactApplicationContext(), name, Toast.LENGTH_LONG).show();
    }

    /*
     * XGPushConfig
     * @description 	Push服务配置项接口
     * */
    @ReactMethod
    public void enableDebug(boolean debugMode) {
        XGPushConfig.enableDebug(context, debugMode);
    }

    @ReactMethod
    public void setAccessId(long accessId) {
        XGPushConfig.setAccessId(context, accessId);
    }

    @ReactMethod
    public void setAccessKey(String accessKey) {
        XGPushConfig.setAccessKey(context, accessKey);
    }

    @ReactMethod
    public void getToken(Promise promise) {
        String token = XGPushConfig.getToken(context);
        Log.d("TPush", "token：" + token);
        promise.resolve(token);
    }

    @ReactMethod
    public void setReportNotificationStatusEnable(boolean debugMode) {
        XGPushConfig.setReportNotificationStatusEnable(context, debugMode);
    }

    @ReactMethod
    public void setReportApplistEnable(boolean debugMode) {
        XGPushConfig.setReportApplistEnable(context, debugMode);
    }

    @ReactMethod
    public void enableOtherPush(boolean flag) {
        XGPushConfig.enableOtherPush(context, flag);
    }

    @ReactMethod
    public void setMiPushAppId(String appid) {
        XGPushConfig.setMiPushAppId(context, appid);
    }

    @ReactMethod
    public void setMiPushAppKey(String appkey) {
        XGPushConfig.setMiPushAppKey(context, appkey);
    }

    @ReactMethod
    public void setMzPushAppId(String appid) {
        XGPushConfig.setMzPushAppId(context, appid);
    }

    @ReactMethod
    public void setMzPushAppKey(String appkey) {
        XGPushConfig.setMzPushAppKey(context, appkey);
    }

    @ReactMethod
    public void setHuaweiDebug(boolean isHuaweiDebug) {
        XGPushConfig.setHuaweiDebug(isHuaweiDebug);
    }

    @ReactMethod
    public void registerPush() {
        XGPushManager.registerPush(context/*,new XGIOperateCallback() {
            @Override
            public void onSuccess(Object data, int flag) {
                //token在设备卸载重装的时候有可能会变
                Log.d("TPush", "注册成功，设备token为：" + data);
                WritableMap params = Arguments.createMap();
                params.putString("token", (String)data);
                params.putBoolean("isSuccess", true);
                sendEvent(RNXG_ON_REGISTER, params);
            }

            @Override
            public void onFail(Object data, int errCode, String msg) {
                Log.d("TPush", "注册失败，错误码：" + errCode + ",错误信息：" + msg);
                WritableMap params = Arguments.createMap();
                params.putString("msg", msg);
                params.putInt("errCode", errCode);
                params.putBoolean("isSuccess", false);
                sendEvent(RNXG_ON_REGISTER, params);
            }
        }*/);
    }

    @ReactMethod
    public void cancelAllNotifaction(Promise promise) {
        XGPushManager.cancelAllNotifaction(context);
        promise.resolve(null);
    }

    @ReactMethod
    public void getLaunchAppNotification(Promise promise) {
        promise.resolve(launchAppNotification);
    }

    @ReactMethod
    public void notifyJsDidLoad(Promise promise) {
        if (getReactApplicationContext().hasActiveCatalystInstance()) {
            jsDidLoad = true;
            promise.resolve(0);
        }
    }

    protected static boolean isJsDidLoad(){
        return jsDidLoad;
    }

    protected static void setLaunchAppNotification(WritableMap params){
        launchAppNotification = params;
    }

    @ReactMethod
    public void popCachedNotifications(Promise promise) {
        WritableArray array = Arguments.createArray();
        initNotificationCache(this.context);

        int len = notificationIdList.length();
        if(len > 0){
            for (int i = 0; i < len; i++){
                String notificationId = notificationIdList.optString(0);
                if(null != notificationId){
                    WritableMap map = Arguments.createMap();
                    JSONObject notification = notificationCache.getAsJSONObject(notificationId);
                    if(null != notification){
                        /*Iterator<String> it =  notification.keys();
                        while(it.hasNext()){
                            String key = it.next();

                        }*/
                        map.putString("msgId",notificationId);
                        map.putString("customContent",notification.optString("customContent"));
                        array.pushMap(map);
                        notificationCache.remove(notificationId);
                    }
                    notificationIdList.remove(0);
                }
            }
            notificationCache.put(NOTIFICATION_CACHE_NAME,notificationIdList);
        }

        promise.resolve(array);
    }

    private static void initNotificationCache(Context context){
        if(null == notificationCache){
            synchronized (notificationCacheLockObject){
                if( null == notificationCache){
                    notificationCache = ACache.get(context,NOTIFICATION_CACHE_NAME);
                    notificationIdList = notificationCache.getAsJSONArray(NOTIFICATION_CACHE_NAME);
                    if(null == notificationIdList){
                        notificationIdList = new JSONArray();
                    }
                }
            }
        }
    }

    protected static void cacheNotification(Context context, XGPushShowedResult xgPushShowedResult){
        initNotificationCache(context);

        String notificationId = String.valueOf(xgPushShowedResult.getMsgId());
        notificationIdList.put(notificationId);
        notificationCache.put(NOTIFICATION_CACHE_NAME,notificationIdList);//保存推送ID列表
        JSONObject map = new JSONObject();
        try {
            map.put("customContent", xgPushShowedResult.getCustomContent());
        } catch (JSONException e) {
            e.printStackTrace();
        }
        notificationCache.put(notificationId,map);//保存推送信息
    }

    /*
     * 广播类
     * */
    public static class TPushReceiver extends XGPushBaseReceiver {

        /*注册回调*/
        @Override
        public void onRegisterResult(Context context, int code, XGPushRegisterResult xgPushRegisterResult) {
            Log.d("TPush", "注册结果为：" + xgPushRegisterResult);
            WritableMap params = Arguments.createMap();
            params.putBoolean("isSuccess",XGPushBaseReceiver.SUCCESS==code);
            params.putString("token", xgPushRegisterResult.getToken());
            params.putInt("errCode", code);
            params.putString("msg", ReturnCode.errCodeToMsg(code));
            if(isJsDidLoad()) {
                sendEvent(RNXG_ON_REGISTER, params);
            }
        }

        /*注销回调*/
        @Override
        public void onUnregisterResult(Context context, int code) {
            WritableMap params = Arguments.createMap();
            params.putBoolean("isSuccess",XGPushBaseReceiver.SUCCESS==code);
            params.putInt("errCode", code);
            params.putString("msg", ReturnCode.errCodeToMsg(code));
            sendEvent(RNXG_ON_UNREGISTER, params);
        }

        /*设置标签*/
        @Override
        public void onSetTagResult(Context context, int code, String tagName) {
            WritableMap params = Arguments.createMap();
            params.putBoolean("isSuccess",XGPushBaseReceiver.SUCCESS==code);
            params.putInt("errCode", code);
            params.putString("msg", ReturnCode.errCodeToMsg(code));
            params.putString("tagName", tagName);
            sendEvent(RNXG_ON_SET_TAG, params);
        }

        /*删除标签*/
        @Override
        public void onDeleteTagResult(Context context, int code, String tagName) {
            WritableMap params = Arguments.createMap();
            params.putBoolean("isSuccess",XGPushBaseReceiver.SUCCESS==code);
            params.putInt("errCode", code);
            params.putString("msg", ReturnCode.errCodeToMsg(code));
            params.putString("tagName", tagName);
            sendEvent(RNXG_ON_DELETE_TAG, params);
        }

        /*应用内消息的回调*/
        @Override
        public void onTextMessage(Context context, XGPushTextMessage xgPushTextMessage) {
            WritableMap params = Arguments.createMap();
            params.putString("title", xgPushTextMessage.getTitle());
            params.putString("content", xgPushTextMessage.getContent());
            params.putString("customContent", xgPushTextMessage.getCustomContent());
            sendEvent(RNXG_TEXTMESSAGE_ON_RECEIVE, params);
        }

        /*通知被点击触发的回调*/
        @Override
        public void onNotifactionClickedResult(Context context, XGPushClickedResult xgPushClickedResult) {

            if (xgPushClickedResult != null && NotificationAction.clicked.getType() == xgPushClickedResult.getActionType()) { //由信鸽的通知引起打开动作
                WritableMap params = Arguments.createMap();
                params.putString("msgId", String.valueOf(xgPushClickedResult.getMsgId()));
                params.putString("title", xgPushClickedResult.getTitle());
                params.putString("content", xgPushClickedResult.getContent());
//                params.putString("activityName", xgPushClickedResult.getActivityName());
                params.putString("customContent", xgPushClickedResult.getCustomContent());
                params.putInt("actionType", (int)xgPushClickedResult.getActionType());
                if(isJsDidLoad()){
                    sendEvent(RNXG_NOTIFICATION_ON_CLICK, params);
                }else{
                    setLaunchAppNotification(params);
                }
            }
        }

        /*通知被展示触发的回调*/
        @Override
        public void onNotifactionShowedResult(Context context, XGPushShowedResult xgPushShowedResult) {
            WritableMap params = Arguments.createMap();
            params.putString("msgId", String.valueOf(xgPushShowedResult.getMsgId()));
            params.putString("title", xgPushShowedResult.getTitle());
            params.putString("content", xgPushShowedResult.getContent());
//            params.putString("activityName", xgPushShowedResult.getActivity());
            params.putString("customContent", xgPushShowedResult.getCustomContent());
            /* File file = new File(Environment.getExternalStorageDirectory(), "xgpush.txt");
            if (file.exists()) {
                file.delete();
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } */
            // try {
                // FileWriter fw = new FileWriter(file);
                if(isJsDidLoad()) {
                    // fw.write("通知rn");
                    sendEvent(RNXG_NOTIFICATION_ON_RECEIVE, params);
                }else{
                    // fw.write("缓存");
                    //缓存
                    cacheNotification(context, xgPushShowedResult);
                }
            //     fw.close();
            // } catch (IOException e) {
            //     e.printStackTrace();
            // }
        }
    }
}
